#include "stdafx.h"

#include "RectEd.h"
#include "AllLookFeel.h"
#include "Cursor.h"


RectEd::RectEd(MGUI_Widget * _parent)
		: MGUI_Widget(NULL, _parent)
{
	{
		mLeft = new MGUI_Widget(AllLookFeel::Instance()->GetWhite(), this);
		mTop = new MGUI_Widget(AllLookFeel::Instance()->GetWhite(), this);
		mRight = new MGUI_Widget(AllLookFeel::Instance()->GetWhite(), this);
		mBottom = new MGUI_Widget(AllLookFeel::Instance()->GetWhite(), this);

		mLeft->SetPickFlag(MGUI_PickFlag::None);
		mTop->SetPickFlag(MGUI_PickFlag::None);
		mRight->SetPickFlag(MGUI_PickFlag::None);
		mBottom->SetPickFlag(MGUI_PickFlag::None);

		mLeft->SetColor(MGUI_Color(0, 0, 1, 0.8f));
		mTop->SetColor(MGUI_Color(0, 0, 1, 0.8f));
		mRight->SetColor(MGUI_Color(0, 0, 1, 0.8f));
		mBottom->SetColor(MGUI_Color(0, 0, 1, 0.8f));
	}

	{
		mLeftCl = new MGUI_Widget(AllLookFeel::Instance()->GetWhite(), this);
		mTopCl = new MGUI_Widget(AllLookFeel::Instance()->GetWhite(), this);
		mRightCl = new MGUI_Widget(AllLookFeel::Instance()->GetWhite(), this);
		mBottomCl = new MGUI_Widget(AllLookFeel::Instance()->GetWhite(), this);

		mLeftCl->SetPickFlag(MGUI_PickFlag::None);
		mTopCl->SetPickFlag(MGUI_PickFlag::None);
		mRightCl->SetPickFlag(MGUI_PickFlag::None);
		mBottomCl->SetPickFlag(MGUI_PickFlag::None);

		mLeftCl->SetColor(MGUI_Color(0, 1, 0, 0.8f));
		mTopCl->SetColor(MGUI_Color(0, 1, 0, 0.8f));
		mRightCl->SetColor(MGUI_Color(0, 1, 0, 0.8f));
		mBottomCl->SetColor(MGUI_Color(0, 1, 0, 0.8f));
	}


	mLeftLn = new MGUI_Widget(NULL, this);
	mRightLn = new MGUI_Widget(NULL, this);
	mTopLn = new MGUI_Widget(NULL, this);
	mBottomLn = new MGUI_Widget(NULL, this);

	mLeftLn->SetOrder(1);
	mRightLn->SetOrder(1);
	mTopLn->SetOrder(1);
	mBottomLn->SetOrder(1);

	mLeftLn->eventMouseSetFocus += OnLeftSetFocus(this, &RectEd::OnLeftSetFocus_);
	mRightLn->eventMouseSetFocus += OnRightSetFocus(this, &RectEd::OnRightSetFocus_);
	mTopLn->eventMouseSetFocus += OnTopSetFocus(this, &RectEd::OnTopSetFocus_);
	mBottomLn->eventMouseSetFocus += OnBottomSetFocus(this, &RectEd::OnBottomSetFocus_);

	mLeftLn->eventMouseLostFocus += OnLeftLostFocus(this, &RectEd::OnLeftLostFocus_);
	mRightLn->eventMouseLostFocus += OnRightLostFocus(this, &RectEd::OnRightLostFocus_);
	mTopLn->eventMouseLostFocus += OnTopLostFocus(this, &RectEd::OnTopLostFocus_);
	mBottomLn->eventMouseLostFocus += OnBottomLostFocus(this, &RectEd::OnBottomLostFocus_);

	mLeftLn->eventMouseDrag += OnLeftDrag(this, &RectEd::OnLeftDrag_);
	mRightLn->eventMouseDrag += OnRightDrag(this, &RectEd::OnRightDrag_);
	mTopLn->eventMouseDrag += OnTopDrag(this, &RectEd::OnTopDrag_);
	mBottomLn->eventMouseDrag += OnBottomDrag(this, &RectEd::OnBottomDrag_);
}

RectEd::~RectEd()
{
}

void RectEd::SetEditRect(const MGUI_Rect & _rect)
{
	if (GetRect() == _rect)
		return ;

	SetRect(_rect);
	_updateRect();
	_updateClient();

	evRectChanged(_rect);
}

void RectEd::SetEditClient(const MGUI_ClientRect & client)
{
	mClient = client;
	_updateClient();
}

const MGUI_Rect & RectEd::GetEditRect()
{
	return GetRect();
}

void RectEd::_updateRect()
{
	const MGUI_Rect & _rect = GetRect();
	MGUI_Rect rcLeft, rcTop, rcRight, rcBottom;

	int dx = _rect.DX(), dy = _rect.DY();

	{
		rcLeft.x0 = 0;
		rcLeft.x1 = 1;
		rcLeft.y0 = 0;
		rcLeft.y1 = dy;

		rcTop.x0 = 0;
		rcTop.x1 = dx;
		rcTop.y0 = 0;
		rcTop.y1 = 1;

		rcRight.x0 = dx - 1;
		rcRight.x1 = dx;
		rcRight.y0 = 0;
		rcRight.y1 = dy;

		rcBottom.x0 = 0;
		rcBottom.x1 = dx;
		rcBottom.y0 = dy - 1;
		rcBottom.y1 = dy;

		mLeft->SetRect(rcLeft);
		mTop->SetRect(rcTop);
		mRight->SetRect(rcRight);
		mBottom->SetRect(rcBottom);
	}

	{
		rcLeft.x0 = 0;
		rcLeft.x1 = 5;
		rcLeft.y0 = 0;
		rcLeft.y1 = dy;

		rcTop.x0 = 0;
		rcTop.x1 = dx;
		rcTop.y0 = 0;
		rcTop.y1 = 5;

		rcRight.x0 = dx - 5;
		rcRight.x1 = dx;
		rcRight.y0 = 0;
		rcRight.y1 = dy;

		rcBottom.x0 = 0;
		rcBottom.x1 = dx;
		rcBottom.y0 = dy - 5;
		rcBottom.y1 = dy;

		mLeftLn->SetRect(rcLeft);
		mTopLn->SetRect(rcTop);
		mRightLn->SetRect(rcRight);
		mBottomLn->SetRect(rcBottom);
	}
}

void RectEd::_updateClient()
{
	MGUI_Rect _rect = GetRect();
	MGUI_Rect rcLeft, rcTop, rcRight, rcBottom;

	int x0 = mClient.dx0;
	int y0 = mClient.dy0;
	int x1 = _rect.DX() - mClient.dx1;
	int y1 = _rect.DY() - mClient.dy1;

	rcLeft.x0 = x0;
	rcLeft.x1 = x0 + 1;
	rcLeft.y0 = y0;
	rcLeft.y1 = y1;

	rcTop.x0 = x0;
	rcTop.x1 = x1;
	rcTop.y0 = y0;
	rcTop.y1 = y0 + 1;

	rcRight.x0 = x1 - 1;
	rcRight.x1 = x1;
	rcRight.y0 = y0;
	rcRight.y1 = y1;

	rcBottom.x0 = x0;
	rcBottom.x1 = x1;
	rcBottom.y0 = y1 - 1;
	rcBottom.y1 = y1;

	mLeftCl->SetRect(rcLeft);
	mTopCl->SetRect(rcTop);
	mRightCl->SetRect(rcRight);
	mBottomCl->SetRect(rcBottom);

	if (mClient == MGUI_ClientRect())
	{
		mLeftCl->SetVisible(false);
		mTopCl->SetVisible(false);
		mRightCl->SetVisible(false);
		mBottomCl->SetVisible(false);
	}
	else
	{
		mLeftCl->SetVisible(true);
		mTopCl->SetVisible(true);
		mRightCl->SetVisible(true);
		mBottomCl->SetVisible(true);
	}

}

void RectEd::OnMouseLostFocus(MGUI_Widget* _new)
{
	Cursor::Instance()->Unbind();
}

void RectEd::OnMouseSetFocus(MGUI_Widget* _old)
{
	Cursor::Instance()->Bind(Cursor::kSize);
}

void RectEd::OnMouseDrag(int _x, int _y)
{
	if (MGUI_InputManager::Instance()->IsMouseCaptured())
	{
		int dx = _x - mX;
		int dy = _y - mY;

		MGUI_Rect rect = GetEditRect();

		rect.x0 += dx;
		rect.x1 += dx;
		rect.y0 += dy;
		rect.y1 += dy;

		mX = _x; mY = _y;

		SetEditRect(rect);
	}
}

void RectEd::OnMousePressed(int _x, int _y, MGUI_MouseButton _id)
{
	if (_id == MGUI_MouseButton::Left)
	{
		mX = _x;
		mY = _y;
	}
}

void RectEd::OnMouseReleased(int _x, int _y, MGUI_MouseButton _id)
{
	if (_id == MGUI_MouseButton::Left)
	{
		mX = _x;
		mY = _y;
	}
}

void RectEd::OnLeftSetFocus_(MGUI_Widget * _old)
{
	Cursor::Instance()->Bind(Cursor::kSizeWE);
}

void RectEd::OnLeftLostFocus_(MGUI_Widget * _new)
{
	Cursor::Instance()->Unbind();
}

void RectEd::OnRightSetFocus_(MGUI_Widget * _old)
{
	Cursor::Instance()->Bind(Cursor::kSizeWE);
}

void RectEd::OnRightLostFocus_(MGUI_Widget * _new)
{
	Cursor::Instance()->Unbind();
}

void RectEd::OnTopSetFocus_(MGUI_Widget * _old)
{
	Cursor::Instance()->Bind(Cursor::kSizeNS);
}

void RectEd::OnTopLostFocus_(MGUI_Widget * _new)
{
	Cursor::Instance()->Unbind();
}

void RectEd::OnBottomSetFocus_(MGUI_Widget * _old)
{
	Cursor::Instance()->Bind(Cursor::kSizeNS);
}

void RectEd::OnBottomLostFocus_(MGUI_Widget * _new)
{
	Cursor::Instance()->Unbind();
}

void RectEd::OnLeftDrag_(int _x, int _y)
{
	MGUI_Rect rect = mParent->GetAbsClientRect();
	MGUI_Rect myRect = GetRect();

	int newX = _x - rect.x0;

	newX = Math::Maximum(newX, 0);
	newX = Math::Minimum(newX, myRect.x1);

	myRect.x0 = newX;

	SetEditRect(myRect);
}

void RectEd::OnRightDrag_(int _x, int _y)
{
	MGUI_Rect rect = mParent->GetAbsClientRect();
	MGUI_Rect myRect = GetRect();

	int newX = _x - rect.x0;

	newX = Math::Minimum(newX, mParent->GetAbsClientRect().DX());
	newX = Math::Maximum(myRect.x0, newX);

	myRect.x1 = newX;

	SetEditRect(myRect);
}

void RectEd::OnTopDrag_(int _x, int _y)
{
	MGUI_Rect rect = mParent->GetAbsClientRect();
	MGUI_Rect myRect = GetRect();

	int newY = _y - rect.y0;

	newY = Math::Maximum(newY, 0);
	newY = Math::Minimum(newY, myRect.y1);

	myRect.y0 = newY;

	SetEditRect(myRect);
}

void RectEd::OnBottomDrag_(int _x, int _y)
{
	MGUI_Rect rect = mParent->GetAbsClientRect();
	MGUI_Rect myRect = GetRect();

	int newY = _y - rect.y0;

	newY = Math::Minimum(newY, mParent->GetAbsClientRect().DY());
	newY = Math::Maximum(myRect.y0, newY);

	myRect.y1 = newY;

	SetEditRect(myRect);
}

